﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Asset.cs" company="Anton Frattaroli">
//   Copyright (c) Anton Frattaroli. All rights reserved.
// </copyright>
// <summary>
//   Defines the Asset class.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Lidocaine.Data
{
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.SqlClient;
    using System.Globalization;
    using Lidocaine.BusinessObjects;
    
    /// <summary>
    /// Defines the Asset class.
    /// </summary>
    public static class Asset
    {
        /// <summary>
        /// Selects an asset based on its identifier.
        /// </summary>
        /// <param name="id">The asset's identifier.</param>
        /// <returns>The instantiated asset.</returns>
        public static BusinessObjects.Asset Select(int id)
        {
            LazyAsset asset = null;
            using (SqlConnection conn = new SqlConnection(Environment.ConnectionString))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("Lidocaine.GetFileByID", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@FileID", id);
                    using (SqlDataReader rdr = cmd.ExecuteReader())
                    {
                        if (rdr.HasRows)
                        {
                            rdr.Read();
                            asset = new LazyAsset();
                            asset.Id = id;
                            asset.FilePath = rdr["FilePath"].ToString();
                            asset.VirtualPath = rdr["VirtualPath"].ToString();
                            asset.Created = Convert.ToDateTime(rdr["Created"], CultureInfo.InvariantCulture);
                            asset.FileTypeId = Convert.ToInt32(rdr["FileTypeID"], CultureInfo.InvariantCulture);
                        }
                    }
                }
            }

            return asset;
        }

        /// <summary>
        /// Finds a file based on its virtual path, if it exists.
        /// </summary>
        /// <param name="virtualPath">The virtual path to search for.</param>
        /// <returns>If the file is found, an Asset is populated and returned. Returns null otherwise.</returns>
        public static BusinessObjects.Asset Select(string virtualPath)
        {
            LazyAsset asset = null;
            using (SqlConnection conn = new SqlConnection(Environment.ConnectionString))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("Lidocaine.GetFileByVirtualPath", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@VirtualPath", virtualPath);
                    using (SqlDataReader rdr = cmd.ExecuteReader())
                    {
                        if (rdr.HasRows)
                        {
                            rdr.Read();
                            asset = new LazyAsset();
                            asset.Id = Convert.ToInt32(rdr["FileID"], CultureInfo.InvariantCulture);
                            asset.FilePath = rdr["FilePath"].ToString();
                            asset.VirtualPath = virtualPath;
                            asset.Created = Convert.ToDateTime(rdr["Created"], CultureInfo.InvariantCulture);
                            asset.FileTypeId = Convert.ToInt32(rdr["FileTypeID"], CultureInfo.InvariantCulture);
                        }
                    }
                }
            }

            return asset;
        }

        /// <summary>
        /// Finds a list of files with a given file type.
        /// </summary>
        /// <param name="fileType">The filetype of the files to search for.</param>
        /// <returns>A read-only list of files.</returns>
        public static List<BusinessObjects.Asset> SelectAll(BusinessObjects.FileType fileType)
        {
            LazyAsset asset = null;
            List<BusinessObjects.Asset> assets = new List<BusinessObjects.Asset>();
            using (SqlConnection conn = new SqlConnection(Environment.ConnectionString))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("Lidocaine.GetFilesByFileType", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@FileTypeID", fileType.Id);
                    using (SqlDataReader rdr = cmd.ExecuteReader())
                    {
                        if (rdr.HasRows)
                        {
                            while (rdr.Read())
                            {
                                asset = new LazyAsset();
                                asset.Id = Convert.ToInt32(rdr["FileID"], CultureInfo.InvariantCulture);
                                asset.FileTypeId = fileType.Id;
                                asset.FilePath = rdr["FilePath"].ToString();
                                asset.VirtualPath = rdr["VirtualPath"].ToString();
                                asset.Created = Convert.ToDateTime(rdr["Created"], CultureInfo.InvariantCulture);
                                assets.Add(asset);
                            }
                        }
                    }
                }
            }

            return assets;
        }

        public static List<Permission> GetPermissionsWithRoleInfo(string path)
        {
            Permission permission = null;
            List<Permission> permissions = new List<Permission>();
            using (SqlConnection conn = new SqlConnection(Environment.ConnectionString))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("Lidocaine.GetFilePermissionsWithRoleInfo", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@VirtualPath", path);
                    using (SqlDataReader rdr = cmd.ExecuteReader())
                    {
                        if (rdr.HasRows)
                        {
                            while (rdr.Read())
                            {
                                permission = new Permission();
                                permission.Id = Convert.ToInt32(rdr["PermissionID"], CultureInfo.InvariantCulture);
                                permission.AllowType = rdr["PermissionAllowType"].ToString() == "True" ? PermissionAllowType.Role : PermissionAllowType.UserProfile;
                                permission.AllowId = Convert.ToInt32(rdr["PermissionAllowID"], CultureInfo.InvariantCulture);
                                permission.IsActiveDirectoryRole = rdr["ActiveDirectory"] == DBNull.Value ? false : rdr["ActiveDirectory"].ToString() == "True" ? true : false;
                                permission.Name = rdr["RoleName"] != DBNull.Value ? rdr["RoleName"].ToString() : rdr["UserName"] != DBNull.Value ? rdr["UserName"].ToString() : string.Empty;
                                permissions.Add(permission);
                            }
                        }
                    }
                }
            }

            return permissions;
        }

        /// <summary>
        /// Inserts an asset.
        /// </summary>
        /// <param name="asset">The asset to insert.</param>
        /// <returns>The inserted Asset with a newly populated Id field.</returns>
        public static BusinessObjects.Asset Insert(BusinessObjects.Asset asset)
        {
            using (SqlConnection conn = new SqlConnection(Environment.ConnectionString))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("Lidocaine.InsertFile", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@VirtualPath", asset.VirtualPath);
                    cmd.Parameters.AddWithValue("@FileTypeID", asset.FileTypeId);
                    cmd.Parameters.AddWithValue("@FilePath", asset.FilePath ?? string.Empty);
                    asset.Id = Convert.ToInt32(cmd.ExecuteScalar(), CultureInfo.InvariantCulture);
                }
            }

            return asset;
        }

        /// <summary>
        /// Updates an asset.
        /// </summary>
        /// <param name="asset">The asset to update.</param>
        public static void Update(BusinessObjects.Asset asset)
        {
            using (SqlConnection conn = new SqlConnection(Environment.ConnectionString))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("Lidocaine.UpdateFile", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@FileID", asset.Id);
                    cmd.Parameters.AddWithValue("@FilePath", asset.FilePath);
                    cmd.Parameters.AddWithValue("@VirtualPath", asset.VirtualPath);
                    cmd.Parameters.AddWithValue("@FileTypeID", asset.FileTypeId);
                    cmd.ExecuteNonQuery();
                }
            }
        }

        /// <summary>
        /// Deletes an asset.
        /// </summary>
        /// <param name="asset">The asset to delete.</param>
        public static void Delete(BusinessObjects.Asset asset)
        {
            using (SqlConnection conn = new SqlConnection(Environment.ConnectionString))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("Lidocaine.DeleteFile", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@FileID", asset.Id);
                    cmd.ExecuteNonQuery();
                }
            }
        }
    }
}